package com.lucy.rabc.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import com.lucy.common.constant.CommonConst;
import com.lucy.common.constant.HttpStatus;
import com.lucy.common.domain.ResponseDTO;
import com.lucy.common.redis.RedisCache;
import com.lucy.rabc.constant.MenuTypeEnum;
import com.lucy.rabc.domain.vo.LoginVO;
import com.lucy.rabc.domain.vo.RouterVO;
import com.lucy.rabc.entity.SysMenu;
import com.lucy.rabc.entity.SysRole;
import com.lucy.rabc.entity.SysUser;
import com.lucy.rabc.params.GrantParams;
import com.lucy.rabc.params.LoginParams;
import com.lucy.rabc.service.SysMenuService;
import com.lucy.rabc.service.SysRoleMenuService;
import com.lucy.rabc.service.SysRoleService;
import com.lucy.rabc.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author kindear
 * 系统鉴权控制器
 */

@Slf4j
@RestController
@RequestMapping("system")
@Api(tags = "系统鉴权")
public class AuthController {
    @Autowired
    RedisCache redisCache;

    @Autowired
    SysUserService userService;

    @Autowired
    SysMenuService menuService;

    @Autowired
    SysRoleService roleService;


    @PostMapping("qlogin")
    @ApiOperation(value = "快速登录",notes = "")
    public ResponseDTO<Object> qLogin(){
        StpUtil.login(1L);
        return ResponseDTO.succData(
                StpUtil.getTokenValue()
        );
    }




    @PostMapping("login")
    @ApiOperation(value = "用户登录",notes = "")
    public ResponseDTO<Object> login(@RequestBody @Validated LoginParams loginParams){
        Optional<SysUser> userOp = userService.getByUserName(loginParams.getUsername());
        if (!userOp.isPresent()) {
            return ResponseDTO.wrap(HttpStatus.NOT_FOUND);
        }
        SysUser user = userOp.get();
        String captchaCode = redisCache.getCacheObject(loginParams.getUuid());
        log.debug("UUID:["+loginParams.getUuid()+"]对应的验证码为:"+captchaCode);
        //清除缓存中的图片
        redisCache.deleteObject(CommonConst.CAPTCHA_CODE_KEY.concat(loginParams.getUuid()));
        if(!captchaCode.equals(loginParams.getCode())){
            return ResponseDTO.wrap(HttpStatus.BAD_REQUEST,"验证码错误");
        }
        //比对密码
        if (!loginParams.getPassword().equals(user.getPassword())){
            return ResponseDTO.wrap(HttpStatus.BAD_REQUEST,"登录密码错误");
        }
        //执行登录
        StpUtil.login(user.getId());
        LoginVO loginVO = new LoginVO();
        BeanUtil.copyProperties(user,loginVO, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        loginVO.setToken(StpUtil.getTokenValue());
        return ResponseDTO.succData(loginVO);
    }

    @PostMapping("logout")
    @ApiOperation(value = "用户登出",notes = "")
    public ResponseDTO<Object> logout(){
        StpUtil.logout();
        return ResponseDTO.succMsg("登出成功");
    }


    @GetMapping("routers")
    @ApiOperation(value = "获取路由",notes = "")
    public ResponseDTO<Object> routersBuild(@RequestParam(value = "userId",required = false) Long userId){
        Long loginId = null;
        if (Validator.isNotEmpty(userId)){
            loginId = userId;
        }else {
            loginId = StpUtil.getLoginIdAsLong();
        }

        Optional<SysUser> userOp = userService.getOne(loginId);
        if (!userOp.isPresent()){
            return ResponseDTO.wrap(HttpStatus.NOT_FOUND);
        }
        SysUser user = userOp.get();

        Set<SysRole> roleSet = user.getRoles();

        List<Long> roleIdList = roleSet.stream().map(SysRole::getId).collect(Collectors.toList());

        List<Long> menuIds = roleService.getRolesMenuIds(roleIdList);

        menuIds = menuIds.stream().distinct().collect(Collectors.toList());

        List<SysMenu> menus = menuService.getMenus(menuIds);

        //System.out.println(MenuTypeEnum.TYPE_DIR.getType());

        // 过滤
        menus = menus.stream().filter(sysMenu -> {
            return sysMenu.getMenuType().equals(MenuTypeEnum.TYPE_DIR.getType());
        }).collect(Collectors.toList());

        List<RouterVO> routers = menuService.buildMenus(menus);

        return ResponseDTO.succData(routers);

    }


}
